package com.xiao.mall.foundation.config;


import com.xiao.mall.foundation.datasource.DynamicRoutingDataSource;
import com.xiao.mall.foundation.datasource.DynamicRoutingDataSourceContext;
import com.xiao.mall.foundation.datasource.JpaTransactionManagerEx;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
@Component
@Slf4j
@ConditionalOnProperty(prefix = "spring.datasource.slave", name = "enable", havingValue = "true", matchIfMissing = false)
public class DynamicDatabaseConfiguration {

    @Value("${spring.datasource.slave.url:}")
    private String url;

    @Bean("masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    @LiquibaseDataSource
    public DataSource masterDataSource(DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().build();
    }

    @Bean("slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave.hikari")
    public DataSource slaveDataSource(DataSourceProperties properties) {
        final DataSourceBuilder<?> dataSourceBuilder = properties.initializeDataSourceBuilder();
        if (StringUtils.hasText(url)) {
            dataSourceBuilder.url(url);
        }

        return dataSourceBuilder.build();
    }

    @Bean("dataSource")
    @Primary
    public DataSource dataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
                                 @Qualifier("slaveDataSource") DataSource slaveDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DynamicRoutingDataSourceContext.MASTER, masterDataSource);
        targetDataSources.put(DynamicRoutingDataSourceContext.SLAVE, slaveDataSource);

        DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
        dataSource.setTargetDataSources(targetDataSources);
        dataSource.setDefaultTargetDataSource(masterDataSource);

        return dataSource;
    }

    @Bean(name = "transactionManager")
    public JpaTransactionManagerEx transactionManager(EntityManagerFactory entityManagerFactory) {
        JpaTransactionManagerEx transactionManager = new JpaTransactionManagerEx();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }
}
